package com.core.sdk.utils;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;

import com.core.sdk.core.LogUtil;

/**
 * Image utilities
 */
public class ImageUtil {

	private static final String TAG = "ImageUtil";

	/**
	 * Get a bitmap from the image path
	 * 
	 * @param imagePath
	 * @return bitmap or null if read fails
	 */
	public static Bitmap getBitmap(final String imagePath) {
		return getBitmap(imagePath, 1);
	}

	/**
	 * Get a bitmap from the image path
	 * 
	 * @param imagePath
	 * @param sampleSize
	 * @return bitmap or null if read fails
	 */
	public static Bitmap getBitmap(final String imagePath, int sampleSize) {
		final Options options = new Options();
		options.inDither = false;
		options.inSampleSize = sampleSize;

		RandomAccessFile file = null;
		try {
			file = new RandomAccessFile(imagePath, "r");
			return BitmapFactory.decodeFileDescriptor(file.getFD(), null, options);
		} catch (IOException e) {
			Log.d(TAG, e.getMessage(), e);
			return null;
		} finally {
			if (file != null)
				try {
					file.close();
				} catch (IOException e) {
					Log.d(TAG, e.getMessage(), e);
				}
		}
	}

	/**
	 * Get a bitmap from the image
	 * 
	 * @param image
	 * @param sampleSize
	 * @return bitmap or null if read fails
	 */
	public static Bitmap getBitmap(final byte[] image, int sampleSize) {
		final Options options = new Options();
		options.inDither = false;
		options.inSampleSize = sampleSize;
		return BitmapFactory.decodeByteArray(image, 0, image.length, options);
	}

	/**
	 * Get scale for image of size and max height/width
	 * 
	 * @param size
	 * @param width
	 * @param height
	 * @return scale
	 */
	public static int getScale(Point size, int width, int height) {
		if (size.x > width || size.y > height)
			return Math.max(Math.round((float) size.y / (float) height), Math.round((float) size.x / (float) width));
		else
			return 1;
	}

	/**
	 * Get size of image
	 * 
	 * @param imagePath
	 * @return size
	 */
	public static Point getSize(final String imagePath) {
		final Options options = new Options();
		options.inJustDecodeBounds = true;

		RandomAccessFile file = null;
		try {
			file = new RandomAccessFile(imagePath, "r");
			BitmapFactory.decodeFileDescriptor(file.getFD(), null, options);
			return new Point(options.outWidth, options.outHeight);
		} catch (IOException e) {
			Log.d(TAG, e.getMessage(), e);
			return null;
		} finally {
			if (file != null)
				try {
					file.close();
				} catch (IOException e) {
					Log.d(TAG, e.getMessage(), e);
				}
		}
	}

	/**
	 * Get size of image
	 * 
	 * @param image
	 * @return size
	 */
	public static Point getSize(final byte[] image) {
		final Options options = new Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeByteArray(image, 0, image.length, options);
		return new Point(options.outWidth, options.outHeight);
	}

	/**
	 * Get bitmap with maximum height or width
	 * 
	 * @param imagePath
	 * @param width
	 * @param height
	 * @return image
	 */
	public static Bitmap getBitmap(final String imagePath, int width, int height) {
		Point size = getSize(imagePath);
		return getBitmap(imagePath, getScale(size, width, height));
	}

	/**
	 * Get bitmap with maximum height or width
	 * 
	 * @param image
	 * @param width
	 * @param height
	 * @return image
	 */
	public static Bitmap getBitmap(final byte[] image, int width, int height) {
		Point size = getSize(image);
		return getBitmap(image, getScale(size, width, height));
	}

	/**
	 * Get bitmap with maximum height or width
	 * 
	 * @param image
	 * @param width
	 * @param height
	 * @return image
	 */
	public static Bitmap getBitmap(final File image, int width, int height) {
		return getBitmap(image.getAbsolutePath(), width, height);
	}

	/**
	 * Get a bitmap from the image file
	 * 
	 * @param image
	 * @return bitmap or null if read fails
	 */
	public static Bitmap getBitmap(final File image) {
		return getBitmap(image.getAbsolutePath());
	}

	public static Bitmap cropBitmap(Bitmap bitmap, int width, int height) {
		Log.d(TAG, "width,height = " + width + "," + height);

		int origWidth = bitmap.getWidth();
		int origHeight = bitmap.getHeight();

		Log.d(TAG, "origWidth, origHeight = " + origWidth + "," + origHeight);
		float scale = Math.max((float) height / (float) origHeight, (float) width / (float) origWidth);
		Matrix matrix = new Matrix();
		matrix.setScale(scale, scale);
		Bitmap roomedBitmap = Bitmap.createBitmap(bitmap, 0, 0, origWidth, origHeight, matrix, true);
		origWidth = roomedBitmap.getWidth();
		origHeight = roomedBitmap.getHeight();
		Log.d(TAG, "roomedBitmap width,height = " + origWidth + "," + origHeight);

		Bitmap cropedBitmap = Bitmap.createBitmap(roomedBitmap, origWidth / 2 - width / 2, origHeight / 2 - height / 2, width, height);
		Log.d(TAG, "cropedBitmap width,height = " + cropedBitmap.getWidth() + "," + cropedBitmap.getHeight());

		if (roomedBitmap != null)
			roomedBitmap.recycle();

		return cropedBitmap;
	}

	public static Bitmap getBitmapFromCamera(Intent intent) {
		if (intent.getExtras() == null) {
			String file = intent.getDataString();
			file = file.substring(7);
			// return ImageUtils.getBitmap(file, 1024, 1024);
			return ImageUtil.getBitmap(file);
		} else {
			return (Bitmap) intent.getExtras().get("data");
		}

	}

	public static Bitmap getBitmapFromFile(String path, int newWidth) {
		if (path == null || path.trim().length() == 0)
			throw new IllegalArgumentException("path is null");
		File f = new File(path);
		if (!f.exists())
			throw new RuntimeException("file:" + path + " not found");
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(f.getAbsolutePath(), opts);
		int inSampleSize = opts.outWidth / newWidth;
		if (opts.outWidth >= newWidth) {
			int height = Math.round((opts.outHeight * 1.0f * newWidth) / opts.outWidth);
			opts.outWidth = newWidth;
			opts.outHeight = height;
		}
		if (inSampleSize <= 0) {
			inSampleSize = 1;
		}
		opts.inPreferredConfig = Config.ARGB_8888;
		opts.inSampleSize = inSampleSize;
		opts.inJustDecodeBounds = false;
		opts.inInputShareable = true;
		opts.inPurgeable = true;
		Bitmap bmp = BitmapFactory.decodeFile(f.getPath(), opts);
		return bmp;
	}

	public static String getLocalPathFromUri(Uri uri, Activity activity) {
		Cursor cursor = null;
		String path = null;
		try {
			cursor = activity.managedQuery(uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null);
			int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			path = cursor.getString(column_index);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (cursor != null && Build.VERSION.SDK_INT < 14) {
				cursor.close();
			}
		}
		return path;
	}

	/**
	 * 设置ImageView跟据图片内容自动缩放
	 * @param iv
	 * @param widthDp 水平间隔,单位dp
	 */
	public static void setAutoLayoutParams(ImageView iv, int widthDp) {
		Bitmap bmp = ((BitmapDrawable) iv.getDrawable()).getBitmap();
		if (bmp == null) {
			LogUtil.w(TAG, "setAutoLayoutParams(),bmp is null");
			return;
		}
		LayoutParams lp = iv.getLayoutParams();
		int w = ScreenUtil.getDisplayMetrics(iv.getContext()).widthPixels - ScreenUtil.dip2px(iv.getContext(), widthDp);
		if (lp == null) {
			lp = new LayoutParams(w, 0);
		}
		lp.width = w;
		lp.height = Math.round(bmp.getHeight() * 1f * lp.width / bmp.getWidth());
		LogUtil.d(TAG, "setAutoLayoutParams(),lp.width=" + lp.width + " lp.height=" + lp.height);
		iv.setLayoutParams(lp);
	}

	/**
	 * 设置ImageView的LayoutParams
	 * @param iv
	 * @param widthDp LayoutParams的宽度
	 * @param heightDp LayoutParams的高度
	 */
	public static void setLayoutParams(View iv, int widthDp, int heightDp) {
		LayoutParams lp = iv.getLayoutParams();
		int w = ScreenUtil.dip2px(iv.getContext(), widthDp);
		int h = ScreenUtil.dip2px(iv.getContext(), heightDp);
		if (lp == null) {
			lp = new LayoutParams(w, h);
		} else {
			lp.width = w;
			lp.height = h;
		}
		iv.setLayoutParams(lp);
	}

}
